home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / Akua Sweets 131 / Akua Sweets Examples / Network / PowerSPrint 142 / PowerSPrint Client next >
Encoding:
Text File  |  1999-03-04  |  22.8 KB  |  1,024 lines  |  [TEXT/ToyS]

  1. (*
  2. V1.42 ◊ This script is © 1998-1999 by AKUA interactive media AG.
  3.  
  4. See the included documentation for more information.
  5.  
  6. V142/26Feb99/Catch more -911 errors and show better info when it happens
  7. V140/01Feb99/Fix up some prefs stuff
  8. V130/22Jan99/Handle return of printer config
  9. V121/07Jan99/Server Registration routine modified
  10. V120/06Jan99/Support prefs feedback from server
  11. V110/05Jan99/Redid a lot of routines, fixed a lot of bugs
  12. V102/25Jul98/Work on timing problems causing 040 crash in AppleScript
  13. V101/11Jul98/More error checking when talking to server
  14. *)
  15.  
  16. -- User setable properties
  17. property kasAllowAlerts : true -- Set to false to stop any alerts from appearing
  18. property kpsTitle : "PowerSPrint Client"
  19. property kpsVersion : "V1.42"
  20. property kpsTitleW : kpsTitle & " " & kpsVersion
  21. property kpfPrefName : kpsTitle & " V1.3"
  22. property kcnTimeOut : 300 -- Kill operations if not touched in this many seconds
  23. property kcnChunkSize : 25000 -- How many bytes per chunk?
  24.  
  25. property kcnDefUser : "CasaVision"
  26. property kcnDefPass : ""
  27. property kcnUseDef : false -- Set to true to use the above info always
  28.  
  29. -- Internal Properties
  30. property kasFinder : "Finder" -- The Finder
  31. property kasAssumedIdentity : false -- Are we ourselves?
  32. property kcnSetupAsk : true -- Ask once about transfer of settings?
  33. property kasServerName : "PowerSPrint Server"
  34.  
  35. -- Internal Globals
  36. global gpsStatus -- Window with status info
  37. global gpsStatLoc -- Location of status window
  38. global gpsSpool -- Spool folder
  39. global gpsSpoolTypes -- Types of spool files
  40. global gpsConnected -- Connected to server?
  41. global gpsMonCre -- Creator of our PrintMonitor
  42.  
  43. global gcnUser -- User to log into server with
  44. global gcnPass -- Password to log into server with
  45. global gcnLink -- True if we've gotten user/pass
  46.  
  47. global gcnServer -- Alias of PowerSPrint Server
  48. global gcnServProc -- Name of server app
  49. global gcnServMach -- Name of server machine
  50. global gcnServZone -- Name of server zone
  51.  
  52. global gasReady -- Are we ready?
  53.  
  54.  
  55. on run
  56.     init()
  57.     return false
  58. end run
  59.  
  60.  
  61. on init()
  62.     -- Don't have a status window yet?
  63.     if ((the open windows) is {}) then
  64.         set gasReady to false
  65.         set gpsConnected to false
  66.         set gcnLink to false
  67.         set gpsStatus to 0
  68.         pfLoad()
  69.         StatusNew()
  70.         
  71.         -- Must be front process for trap patching to work?!?
  72.         talk as user kcnDefUser ¬
  73.             with password kcnDefPass
  74.     end if
  75.     
  76.     set gasReady to spSetup()
  77. end init
  78.  
  79.  
  80. on idle
  81.     init()
  82.     
  83.     if (not gasReady) then
  84.         ShowState("Waiting for you…")
  85.         return 3
  86.     end if
  87.     
  88.     StatusUpdate()
  89.     
  90.     if (spCount() > 0) then
  91.         ShowState("Working…")
  92.         CopyAll()
  93.         StatusUpdate()
  94.         ShowState("Idle.")
  95.         return 15
  96.     end if
  97.     
  98.     repeat with n from 10 to 1 by -1
  99.         ShowState("Quitting… - you can reposition this window now (" & n & ")")
  100.         pause for 60
  101.     end repeat
  102.     quit
  103. end idle
  104.  
  105.  
  106. on quit
  107.     set gasReady to false
  108.     try
  109.         StatusUpdate()
  110.         pfSave()
  111.         StatusDel()
  112.     on error
  113.         beep
  114.     end try
  115.     continue quit
  116. end quit
  117.  
  118.  
  119. on open fsObjs
  120.     init()
  121.     spSetup()
  122.     
  123.     repeat with fsObj in fsObjs
  124.         set fInfo to basic info for fsObj
  125.         
  126.         if (catalog kind of fInfo) is a folder then
  127.             spSet(fsObj)
  128.         else if (system type of fInfo) is "APPL" then
  129.             if (system creator of fInfo is "dplt") then
  130.                 cnServerSet(fsObj)
  131.             else
  132.                 pmSet(fsObj)
  133.             end if
  134.         else if not gasReady then
  135.             display dialog "Please set me up first!" buttons {"Yo!"} default button 1
  136.         else
  137.             CopyOne(0, fsObj)
  138.         end if
  139.     end repeat
  140.     
  141.     spSetup()
  142. end open
  143.  
  144.  
  145. on pfLoad()
  146.     try
  147.         set prefs to load preference named kpfPrefName
  148.     on error err number errNum
  149.         set prefs to ¬
  150.             {PfStatLoc:{40, 60} ¬
  151.                 , PfServer:0 ¬
  152.                 , PfSpool:path to printmonitor ¬
  153.                 , PfSpoolTypes:{} ¬
  154.                 , PfMonCre:("????") ¬
  155.                 , PfServProc:("") ¬
  156.                 , PfServMach:("") ¬
  157.                 , PfServZone:("") ¬
  158.                 }
  159.     end try
  160.     
  161.     -- Globals from prefs
  162.     set gpsStatLoc to PfStatLoc of prefs
  163.     set gcnServer to PfServer of prefs
  164.     set gpsSpool to PfSpool of prefs
  165.     set gpsSpoolTypes to PfSpoolTypes of prefs
  166.     set gpsMonCre to PfMonCre of prefs
  167.     set gcnServProc to PfServProc of prefs
  168.     set gcnServMach to PfServMach of prefs
  169.     set gcnServZone to PfServZone of prefs
  170.     
  171.     -- Validate Spool Folder
  172.     try
  173.         set x to resolve chain gpsSpool
  174.     on error
  175.         set gpsSpool to path to printmonitor
  176.     end try
  177. end pfLoad
  178.  
  179.  
  180. on pfSave()
  181.     if (gpsStatus is not 0) then
  182.         set newLoc to screen location of ¬
  183.             (display info gpsStatus message "Saving prefs…" at line 2) -- Action
  184.         if (newLoc is not gpsStatLoc) then set gpsStatLoc to newLoc
  185.     end if
  186.     
  187.     -- Appending {} to the end of this causes crashes in System 7.x
  188.     set prefs to ¬
  189.         {PfStatLoc:gpsStatLoc ¬
  190.             , PfServer:gcnServer ¬
  191.             , PfSpool:gpsSpool ¬
  192.             , PfSpoolTypes:gpsSpoolTypes ¬
  193.             , PfMonCre:gpsMonCre ¬
  194.             , PfServProc:gcnServProc ¬
  195.             , PfServMach:gcnServMach ¬
  196.             , PfServZone:gcnServZone ¬
  197.             }
  198.     
  199.     save preference prefs named kpfPrefName
  200.     ShowAction("Saved.")
  201. end pfSave
  202.  
  203.  
  204. on pmSet(fsObj)
  205.     ShowAction("Setting Monitor…")
  206.     
  207.     set fInfo to basic info for fsObj
  208.     set fic to the icon for fsObj
  209.     collate fsObj with the trasher
  210.     
  211.     set myAlias to path to me
  212.     
  213.     set the catalog info of myAlias to fInfo
  214.     set the icon of myAlias to fic
  215.     collate myAlias renaming it to (catalog name of fInfo)
  216.     
  217.     set gpsMonCre to (system creator of fInfo)
  218.     set kasAssumedIdentity to true
  219.     pfSave()
  220. end pmSet
  221.  
  222.  
  223. on spSet(fsObj)
  224.     set gpsSpool to fsObj
  225.     pfSave()
  226. end spSet
  227.  
  228.  
  229. on spCount()
  230.     if (gpsSpoolTypes is {} and gpsMonCre is "????") then return 0
  231.     return the number of items in ¬
  232.         (the entries in gpsSpool whose creators are in {gpsMonCre})
  233. end spCount
  234.  
  235.  
  236. on spCheckLamers()
  237.     set orphs to (the entries in gpsSpool whose types are in {"Part"})
  238.     set daddy to (gpsSpool as string)
  239.     
  240.     repeat with orph in orphs
  241.         try
  242.             collate ((daddy & orph) as alias) with the deleter
  243.         on error
  244.             try
  245.                 collate ((daddy & orph) as alias) with the trasher
  246.             on error
  247.                 ShowError("Couldn't remove spool file:" & orph)
  248.             end try
  249.         end try
  250.     end repeat
  251. end spCheckLamers
  252.  
  253.  
  254. on StatusNew()
  255.     set gpsStatus to ¬
  256.         display info titled kpsTitleW ¬
  257.             message ("Starting up…") ¬
  258.             located at gpsStatLoc
  259.     set gpsStatLoc to screen location of gpsStatus
  260. end StatusNew
  261.  
  262.  
  263. on StatusUpdate()
  264.     if (gpsStatus is not 0) then
  265.         set newLoc to screen location of ¬
  266.             (display info gpsStatus ¬
  267.                 message ("Spooled Files: " & spCount()))
  268.         if (newLoc is not gpsStatLoc) then
  269.             set gpsStatLoc to newLoc
  270.             pfSave()
  271.         end if
  272.     end if
  273. end StatusUpdate
  274.  
  275.  
  276. on ShowState(msg)
  277.     if (gpsStatus is not 0) then ¬
  278.         display info gpsStatus ¬
  279.             message msg
  280. end ShowState
  281.  
  282.  
  283. on Status(msg)
  284.     if (gpsStatus is not 0) then
  285.         display info gpsStatus ¬
  286.             message msg ¬
  287.             at line 2
  288.     end if
  289. end Status
  290.  
  291.  
  292. on ShowAction(msg)
  293.     display info gpsStatus ¬
  294.         message msg ¬
  295.         at line 3 ¬
  296.         using color 16
  297. end ShowAction
  298.  
  299.  
  300. on ShowReady()
  301.     display info gpsStatus ¬
  302.         message ("Ready.") ¬
  303.         at line 3 ¬
  304.         using color (16 * 32)
  305. end ShowReady
  306.  
  307.  
  308. on ShowError(msg)
  309.     if (gpsStatus is not 0) then
  310.         display info gpsStatus ¬
  311.             message msg ¬
  312.             at line 3 ¬
  313.             using color (12 * 1024)
  314.     end if
  315.     set gpsConnected to false
  316.     pause for 300
  317.     return
  318. end ShowError
  319.  
  320.  
  321. on StatusDel()
  322.     display info gpsStatus with disposal
  323.     set gpsStatus to 0
  324. end StatusDel
  325.  
  326.  
  327. on spSetup()
  328.     if gasReady then return true
  329.     
  330.     if (gpsStatus is not 0) then
  331.         display info gpsStatus ¬
  332.             message ("Spool: " & (gpsSpool as string)) ¬
  333.             at line 9 ¬
  334.             using color 16
  335.         
  336.         if (option key down of (input state)) then cnServerChoose()
  337.         
  338.         if (gcnServer is 0) then
  339.             display info gpsStatus ¬
  340.                 message ("WAITING FOR THE SERVER TO BE DROPPED ON ME") ¬
  341.                 at line 3 ¬
  342.                 using color (16 * 1024)
  343.             display info gpsStatus ¬
  344.                 message ("(… or hold the option key down to choose a server)") ¬
  345.                 at line 4 ¬
  346.                 using color (16 * 1024)
  347.             return false
  348.         end if
  349.         
  350.         display info gpsStatus ¬
  351.             message ("Server: " & gcnServZone & ":" & gcnServMach) ¬
  352.             at line 11 ¬
  353.             using color 16 + (16 * 32)
  354.         
  355.         if (control key down of (input state)) then
  356.             try
  357.                 open {choose file with prompt "Choose the Print Monitor" of type {"APPL"}}
  358.             on error
  359.                 beep
  360.             end try
  361.         end if
  362.         
  363.         if (shift key down of (input state)) then
  364.             try
  365.                 open {choose folder with prompt "Choose Spool Folder (e.g. Spool Folder5)"}
  366.             on error
  367.                 beep
  368.             end try
  369.         end if
  370.         
  371.         if (not kasAssumedIdentity) then
  372.             display info gpsStatus ¬
  373.                 message ("WAITING FOR THE \"PRINT MONITOR\" APPLICATION TO BE DROPPED ON ME") ¬
  374.                 at line 3 ¬
  375.                 using color (16 * 1024)
  376.             display info gpsStatus ¬
  377.                 message ("… or choose a different Spool folder by holding Shift") ¬
  378.                 at line 4 ¬
  379.                 using color (16 * 1024)
  380.             display info gpsStatus ¬
  381.                 message ("… or choose the Monitor application by holding Control") ¬
  382.                 at line 5 ¬
  383.                 using color (16 * 1024)
  384.             return false
  385.         end if
  386.         
  387.         CopyAll() -- Try to do current spool files
  388.         
  389.         if (gpsSpoolTypes is {}) then
  390.             display info gpsStatus ¬
  391.                 message ("WAITING TO PROCESS THE FIRST SPOOL FILE(s)") ¬
  392.                 at line 3 ¬
  393.                 using color (16 * 1024)
  394.             display info gpsStatus ¬
  395.                 message ("… or choose a different Spool folder by holding Shift") ¬
  396.                 at line 4 ¬
  397.                 using color (16 * 1024)
  398.             display info gpsStatus ¬
  399.                 message ("…") ¬
  400.                 at line 5 ¬
  401.                 using color 15
  402.             return false
  403.         end if
  404.         
  405.         display info gpsStatus ¬
  406.             message ("…") ¬
  407.             at line 4 ¬
  408.             using color 15
  409.         display info gpsStatus ¬
  410.             message ("…") ¬
  411.             at line 5 ¬
  412.             using color 15
  413.     end if
  414.     
  415.     ShowReady()
  416.     
  417.     return true
  418. end spSetup
  419.  
  420.  
  421. on ServerReg()
  422.     talk as user gcnUser ¬
  423.         with password gcnPass ¬
  424.         on server gcnServMach ¬
  425.         in AppleTalk zone gcnServZone
  426.     
  427.     ShowAction("Checking if server is ready…")
  428.     pause for 2 with seconds timing --?!?
  429.     
  430.     try
  431.         activate
  432.         tell application gcnServProc ¬
  433.             of machine gcnServMach ¬
  434.             of zone gcnServZone to CheckReady()
  435.         set ready to the result
  436.         set gpsConnected to true
  437.     on error errStr number errNum
  438.         ShowError(errStr)
  439.         set ready to false
  440.         set gpsConnected to false
  441.     end try
  442.     
  443.     if (not ready) then return false
  444.     
  445.     ShowAction("Registering…")
  446.     
  447.     tell application gcnServProc ¬
  448.         of machine gcnServMach ¬
  449.         of zone gcnServZone ¬
  450.         to ClientReg()
  451.     set servInfo to the result
  452.     
  453.     -- Check version
  454.     if (SrvrVersion of servInfo) is not kpsVersion then
  455.         display dialog ("WARNING" & return & ¬
  456.             "Server is version " & (SrvrVersion of servInfo) & return & ¬
  457.             "Client is version " & kpsVersion & return & return & ¬
  458.             "This may not work.") buttons {"Uh-Oh"} default button 1
  459.     end if
  460.     
  461.     -- Check printer setup
  462.     ShowAction("Hold control to reset driver setup…")
  463.     if (kcnSetupAsk or (control key down of (input state))) then
  464.         set kcnSetupAsk to false
  465.         if (button returned of (display dialog ("Do you wish to use copy the server's" & ¬
  466.             " page setup and other settings to this client?" & ¬
  467.             return & return & ¬
  468.             "This may be helpful when one of the Macs" & ¬
  469.             " uses a USB and the other a serial connection.") ¬
  470.             buttons {"No", "Yes"} default button 1) is "Yes") then
  471.             ShowAction("Applying server's driver setup…")
  472.             copy SrvrSetup of servInfo to pc
  473.             try
  474.                 set drvr to ¬
  475.                     (((path to extensions folder) as string) & ¬
  476.                         (print driver name of pc)) as alias
  477.                 set print driver alias of pc to (resolve chain drvr)
  478.                 ShowAction("Applied…")
  479.             on error errStr number errNum
  480.                 ShowAction("Failed…")
  481.                 ShowError(errStr)
  482.             end try
  483.             printer configuration pc
  484.             ShowAction("Saved…")
  485.         end if
  486.     end if
  487.     
  488.     -- Check prefs updates
  489.     ShowAction("Scanning driver prefs…")
  490.     
  491.     try
  492.         set epf to (((path to preferences folder) as string) & "Epson Preferences") as alias
  493.     on error
  494.         ShowAction("…")
  495.         return true
  496.     end try
  497.     
  498.     set pffs to SrvrDrvrPrefs of servInfo
  499.     repeat with pff in pffs
  500.         set pname to catalog name of pff
  501.         
  502.         try
  503.             set pfile to ((epf as string) & pname) as alias
  504.             set pinfo to basic info for pfile
  505.             if (catalog modification date of pinfo) ¬
  506.                 is not (catalog modification date of pff) then ¬
  507.                 dvRequestFile(epf, pff)
  508.         on error
  509.             dvRequestFile(epf, pff)
  510.         end try
  511.     end repeat
  512.     
  513.     return true
  514. end ServerReg
  515.  
  516.  
  517. on dvRequestFile(destF, binf)
  518.     ShowAction("Updating driver pref: " & (catalog name of binf))
  519.     
  520.     set pfile to ((destF as string) & (catalog name of binf))
  521.     
  522.     tell application gcnServProc ¬
  523.         of machine gcnServMach ¬
  524.         of zone gcnServZone ¬
  525.         to dvReturnFile(binf)
  526.     set fks to the result
  527.     
  528.     if ((item 1 of fks) is not 0) then -- data fork
  529.         write data to the data fork of pfile from buffer (item 1 of fks)
  530.     end if
  531.     
  532.     if ((item 2 of fks) is not 0) then -- resource fork
  533.         set fk to ¬
  534.             open fork from pfile ¬
  535.                 of type (system type of binf) ¬
  536.                 of creator (system creator of binf) ¬
  537.                 with resource fork and write access
  538.         write data to fk from buffer (item 2 of fks)
  539.         close fork fk
  540.     end if
  541.     
  542.     set the catalog info of pfile to binf
  543. end dvRequestFile
  544.  
  545.  
  546. on cnServerSet(fsObj)
  547.     set aInfo to alias info from fsObj
  548.     set gcnServer to fsObj
  549.     set gcnServProc to original name of aInfo
  550.     set gcnServMach to alias server of aInfo
  551.     set gcnServZone to alias zone of aInfo
  552. end cnServerSet
  553.  
  554.  
  555. on cnServerChoose()
  556.     try
  557.         set myServ to the server processes with prompt ("PowerSPrint: Choose a Server") ¬
  558.             application label ("PowerSPrint Server") named kasServerName ¬
  559.             
  560.     on error
  561.         beep
  562.         return
  563.     end try
  564.     
  565.     set myServ to item 1 of myServ
  566.     set myApp to proc name of myServ
  567.     set gcnServMach to proc mac of myServ
  568.     set gcnServZone to proc zone of myServ
  569.     
  570.     cnGetLoginUser()
  571.     if (not gcnLink) then return
  572.     
  573.     talk as user gcnUser ¬
  574.         with password gcnPass ¬
  575.         on server gcnServMach ¬
  576.         in AppleTalk zone gcnServZone
  577.     
  578.     try
  579.         tell application myApp of machine gcnServMach of zone gcnServZone to ¬
  580.             ClientReg()
  581.         set myRec to the result
  582.     on error errStr
  583.         ShowError(errStr)
  584.         beep
  585.         return
  586.     end try
  587.     
  588.     if (SrvrVersion of myRec) is not kpsVersion then
  589.         display dialog ("The chosen Server is not the same version as this client." & return & ¬
  590.             return & "Please install the same version.") ¬
  591.             buttons {"Damn"} default button 1
  592.         beep
  593.         return
  594.     end if
  595.     
  596.     cnServerSet(SrvrApp of myRec)
  597.     spSetup()
  598. end cnServerChoose
  599.  
  600.  
  601. on cnServerLaunch()
  602.     cnGetLoginUser()
  603.     
  604.     if (not gcnLink) then return false
  605.     
  606.     talk as user gcnUser ¬
  607.         with password gcnPass ¬
  608.         on server gcnServMach ¬
  609.         in AppleTalk zone gcnServZone
  610.     
  611.     ShowAction("Checking server status…")
  612.     
  613.     set servs to the server processes on server gcnServMach ¬
  614.         in AppleTalk zone gcnServZone
  615.     
  616.     if (servs does not contain gcnServProc) then
  617.         if (servs is {}) then
  618.             ShowError("Server is down!")
  619.             return false
  620.         else
  621.             ShowAction("Launching Server…")
  622.             set gpsConnected to false
  623.             -- Temporary fix until we update "talk as user" to handle background linking
  624.             activate
  625.             try
  626.                 tell application kasFinder ¬
  627.                     of machine gcnServMach ¬
  628.                     of zone gcnServZone ¬
  629.                     to open gcnServer
  630.                 
  631.                 ShowAction("Waiting for server…")
  632.                 if not AwaitLaunch(gcnServZone, gcnServMach, gcnServProc) then return false
  633.                 -- If this is too low, the server crashes on a Quadra 700... AppleScript fault
  634.                 repeat with i from 60 to 1 by -1
  635.                     ShowAction("Server launched, waiting: " & i)
  636.                     pause for 59
  637.                 end repeat
  638.                 ShowAction("Contacting Server…")
  639.                 return false
  640.             on error errStr number errNum
  641.                 ShowAction("Can't launch server")
  642.                 ShowError(errStr)
  643.                 if errNum is in {-927, -911} then -- No Auth or unrecog user
  644.                     ShowError("Hold Shift to re-enter user/password")
  645.                     pause for 120
  646.                     if (shift key down of (input state)) then
  647.                         ShowError("… will retry with new user …")
  648.                         GetOneFriend(true)
  649.                     end if
  650.                 end if
  651.                 return false
  652.             end try
  653.         end if
  654.     end if
  655.     
  656.     set ready to true
  657.     
  658.     if (not gpsConnected) then
  659.         ShowAction("Pinging Server…")
  660.         
  661.         set ready to ServerReg()
  662.         
  663.         if ready then
  664.             ShowAction("Server Ready…")
  665.         else
  666.             ShowAction("Waiting for server…")
  667.         end if
  668.     end if
  669.     
  670.     return ready
  671. end cnServerLaunch
  672.  
  673.  
  674. on CopyNew(listOfFilesInSpool)
  675.     if (not cnServerLaunch()) then return -1
  676.     
  677.     set myName to (the network zone name) & ":" & (the network server)
  678.     
  679.     try
  680.         tell application gcnServProc ¬
  681.             of machine gcnServMach ¬
  682.             of zone gcnServZone ¬
  683.             to CopyPrep(myName, listOfFilesInSpool)
  684.         set batchNum to the result
  685.     on error errStr
  686.         ShowError(errStr)
  687.         return -1
  688.     end try
  689.     
  690.     return batchNum
  691. end CopyNew
  692.  
  693.  
  694. on CopyDel(batchNum, kids)
  695.     try
  696.         tell application gcnServProc ¬
  697.             of machine gcnServMach ¬
  698.             of zone gcnServZone ¬
  699.             to CopyDone(batchNum)
  700.         set okToDelete to the result
  701.     on error errStr
  702.         ShowError(errStr)
  703.         return
  704.     end try
  705.     
  706.     ShowAction("Removing spool…")
  707.     
  708.     if (okToDelete) then
  709.         repeat with kid in kids
  710.             try
  711.                 collate (((gpsSpool as string) & kid) as alias) with the deleter
  712.             on error
  713.                 collate (((gpsSpool as string) & kid) as alias) with the trasher
  714.             end try
  715.         end repeat
  716.     end if
  717. end CopyDel
  718.  
  719.  
  720. on CopyAll()
  721.     if (not cnServerLaunch()) then return
  722.     
  723.     ShowAction("Prepare batch…")
  724.     
  725.     set daddy to gpsSpool as string
  726.     set kids to (the entries in gpsSpool whose creators are in {gpsMonCre})
  727.     
  728.     if (kids is not {}) then
  729.         set batchNum to CopyNew(kids)
  730.         if (batchNum < 0) then return
  731.         
  732.         ShowAction("Batch ID: " & batchNum)
  733.         
  734.         set erred to false
  735.         
  736.         repeat with kid in kids
  737.             if (CopyOne(batchNum, (daddy & kid) as alias) is not 0) then
  738.                 set erred to true
  739.                 exit repeat
  740.             end if
  741.         end repeat
  742.         
  743.         if (not erred) then CopyDel(batchNum, kids)
  744.     end if
  745.     
  746.     ShowReady()
  747. end CopyAll
  748.  
  749.  
  750. on CopyOne(batchNum, fsObj)
  751.     if (not cnServerLaunch()) then return -1
  752.     
  753.     ShowAction("Prepare file…")
  754.     
  755.     set myInfo to basic info for fsObj
  756.     
  757.     if (gpsSpoolTypes does not contain (system type of myInfo)) then
  758.         set gpsSpoolTypes to gpsSpoolTypes & (system type of myInfo)
  759.         pfSave()
  760.     end if
  761.     
  762.     ShowAction("Copying " & (catalog name of myInfo))
  763.     
  764.     set pg to ¬
  765.         display progress titled ("PowerSPrint Copy") ¬
  766.             located at {-1, -1} ¬
  767.             subtitled (catalog name of myInfo) ¬
  768.             maximum ((data fork length of myInfo) + (resource fork length of myInfo)) ¬
  769.             labeled "Starting…"
  770.     
  771.     set myName to (the network zone name) & ":" & (the network server)
  772.     
  773.     try
  774.         tell application gcnServProc ¬
  775.             of machine gcnServMach ¬
  776.             of zone gcnServZone ¬
  777.             to CopyBeg(myName, batchNum, myInfo)
  778.         set fid to the result
  779.     on error errStr
  780.         ShowError(errStr)
  781.         display progress pg with disposal
  782.         return -2
  783.     end try
  784.     
  785.     set fLast to 0
  786.     
  787.     repeat with fork from 1 to 2
  788.         set isRsrc to (fork is 1)
  789.         
  790.         set cnt to data fork length of myInfo
  791.         set lbl to "Data Fork"
  792.         
  793.         if isRsrc then
  794.             set cnt to resource fork length of myInfo
  795.             set lbl to "Resource Fork"
  796.         end if
  797.         
  798.         Status("Copying " & lbl)
  799.         
  800.         if (cnt > 0) then
  801.             display progress pg ¬
  802.                 labeled lbl
  803.             
  804.             try
  805.                 tell application gcnServProc ¬
  806.                     of machine gcnServMach ¬
  807.                     of zone gcnServZone ¬
  808.                     to CopyFork(fid, isRsrc)
  809.                 set svErr to the result
  810.             on error errStr
  811.                 ShowError(errStr)
  812.                 display progress pg with disposal
  813.                 return -3
  814.             end try
  815.             
  816.             if (svErr is not 0) then
  817.                 beep
  818.                 ShowError("Server Error: " & svErr)
  819.                 display progress pg with disposal
  820.                 return -4
  821.             end if
  822.             
  823.             set fRef to open fork from fsObj ¬
  824.                 resource fork isRsrc
  825.             
  826.             set fOff to 0
  827.             
  828.             repeat while fOff < cnt
  829.                 set toRead to kcnChunkSize
  830.                 if (fOff + toRead) > cnt then ¬
  831.                     set toRead to cnt - fOff
  832.                 
  833.                 set buf to (read data from fRef ¬
  834.                     at offset fOff ¬
  835.                     using buffer size toRead)
  836.                 
  837.                 Status("Copying " & lbl & " @ " & fOff)
  838.                 
  839.                 try
  840.                     tell application gcnServProc ¬
  841.                         of machine gcnServMach ¬
  842.                         of zone gcnServZone ¬
  843.                         to CopyChunk(fid, isRsrc, buf, fOff)
  844.                     set svErr to the result
  845.                 on error errStr
  846.                     ShowError(errStr)
  847.                     close fork fRef
  848.                     display progress pg with disposal
  849.                     return -5
  850.                 end try
  851.                 
  852.                 if (svErr is not 0) then
  853.                     close fork fRef
  854.                     ShowError("Server Error: " & svErr)
  855.                     display progress pg with disposal
  856.                     return -6
  857.                 end if
  858.                 
  859.                 set fOff to fOff + toRead
  860.                 
  861.                 display progress pg ¬
  862.                     value (fOff + fLast)
  863.             end repeat
  864.             
  865.             close fork fRef
  866.             set fLast to fOff
  867.         end if
  868.     end repeat
  869.     
  870.     display progress pg ¬
  871.         labeled "Finishing…"
  872.     
  873.     try
  874.         with timeout of 300 seconds
  875.             tell application gcnServProc ¬
  876.                 of machine gcnServMach ¬
  877.                 of zone gcnServZone ¬
  878.                 to CopyEnd(fid, 0)
  879.         end timeout
  880.         set svErr to the result
  881.     on error errStr
  882.         ShowError(errStr)
  883.         display progress pg with disposal
  884.         return -7
  885.     end try
  886.     
  887.     if (svErr is not 0) then
  888.         beep
  889.         ShowError("Server Error: " & svErr)
  890.         display progress pg with disposal
  891.         return -8
  892.     end if
  893.     
  894.     if (batchNum is 0) then
  895.         display progress pg ¬
  896.             labeled "Deleting spool file…"
  897.         collate fsObj with the deleter
  898.     end if
  899.     
  900.     display progress pg with disposal
  901.     
  902.     ShowReady()
  903.     
  904.     return 0
  905. end CopyOne
  906.  
  907.  
  908. on cnGetLoginUser()
  909.     if (not gcnLink) then
  910.         if (kcnUseDef) then
  911.             set gcnUser to kcnDefUser
  912.             set gcnPass to kcnDefPass
  913.             set gcnLink to true
  914.         else
  915.             GetOneFriend(false)
  916.         end if
  917.     end if
  918. end cnGetLoginUser
  919.  
  920.  
  921. on GetOneFriend(override)
  922.     set isLink to true -- Only linking in this script!
  923.     set userMode to "linking"
  924.     set passButtons to {"Cancel", "OK"}
  925.     set passButton to 2
  926.     
  927.     if (gcnLink) then
  928.         set defUser to gcnUser
  929.         set defPass to gcnPass
  930.     else
  931.         set defUser to kcnDefUser
  932.         set defPass to kcnDefPass
  933.     end if
  934.     
  935.     set usrPwd to KeyChainLookUp(gcnServZone, gcnServMach, isLink)
  936.     
  937.     if (override or usrPwd is {}) then
  938.         set chosen to display dialog ¬
  939.             ("Enter the friendly " & userMode & ¬
  940.                 " user's name for " & ¬
  941.                 gcnServMach & " in zone " & ¬
  942.                 gcnServZone) ¬
  943.                 default answer defUser ¬
  944.             default button 2 ¬
  945.             with icon note
  946.         
  947.         if (the button returned of chosen is "OK") then
  948.             set defUser to the text returned of chosen
  949.         else
  950.             return
  951.         end if
  952.         
  953.         set chosen to display dialog ¬
  954.             ("Enter the friendly " & userMode & ¬
  955.                 " user's password for " & ¬
  956.                 gcnServMach & " in zone " & ¬
  957.                 gcnServZone) ¬
  958.                 buttons passButtons ¬
  959.             default answer defPass ¬
  960.             default button passButton ¬
  961.             with icon note
  962.         
  963.         if (the button returned of chosen is not "Cancel") then
  964.             set defPass to the text returned of chosen
  965.         else
  966.             return
  967.         end if
  968.         
  969.         -- Save encrypted user/pass for future access
  970.         KeyChainSave(gcnServZone, gcnServMach, isLink, defUser, defPass, "")
  971.     else
  972.         set defUser to item 1 of usrPwd
  973.         set defPass to item 2 of usrPwd
  974.     end if
  975.     
  976.     set gcnLink to true
  977.     set gcnUser to defUser
  978.     set gcnPass to defPass
  979. end GetOneFriend
  980.  
  981.  
  982. on AwaitLaunch(zoneName, machName, procName)
  983.     set n to the clock in offset form
  984.     
  985.     repeat while (the clock in offset form) - n < 30
  986.         set servs to the server processes on server gcnServMach ¬
  987.             in AppleTalk zone gcnServZone
  988.         pause for 120
  989.         if (servs contains procName) then return true
  990.     end repeat
  991.     
  992.     return false
  993. end AwaitLaunch
  994.  
  995.  
  996. property kasKeyChainPassword : "PowerScript" -- Encrypt stored data with this
  997. property kasPrefsFileName : "PowerScript Prefs" -- File name in <Preferences>
  998.  
  999. on KeyChainLookUp(zoneName, serverName, isLinking)
  1000.     set prefOwner to "πSRV"
  1001.     if (isLinking) then set prefOwner to "πLNK"
  1002.     
  1003.     try
  1004.         set myKeyData to load preference named (zoneName & ":" & serverName) ¬
  1005.             of type prefOwner in file named kasPrefsFileName
  1006.     on error
  1007.         return {}
  1008.     end try
  1009.     
  1010.     return (encrypt the data myKeyData with password kasKeyChainPassword)
  1011. end KeyChainLookUp
  1012.  
  1013.  
  1014. on KeyChainSave(zoneName, serverName, isLinking, usr, pwd, ntPwd)
  1015.     set myKey to encrypt the data {usr, pwd, ntPwd} with password kasKeyChainPassword
  1016.     
  1017.     set prefOwner to "πSRV"
  1018.     if (isLinking) then set prefOwner to "πLNK"
  1019.     
  1020.     save preference myKey named (zoneName & ":" & serverName) ¬
  1021.         of type prefOwner ¬
  1022.         in file named kasPrefsFileName
  1023. end KeyChainSave
  1024.